package cn.tedu.csmall.product.repo.impl;

import cn.tedu.csmall.product.pojo.vo.BrandListItemVO;
import cn.tedu.csmall.product.pojo.vo.BrandStandardVO;
import cn.tedu.csmall.product.repo.BrandRedisRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Repository;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 处理品牌缓存的数据访问的实现类
 *
 * @author Chen
 * @since 2023/2/13 11:29:29
 */
@Slf4j
@Repository
public class BrandRedisRepositoryImpl implements BrandRedisRepository {

    private final RedisTemplate<String, Serializable> redisTemplate;

    @Autowired
    public BrandRedisRepositoryImpl(RedisTemplate<String, Serializable> redisTemplate) {
        log.debug("创建处理缓存数据实现类对象：BrandRedisRepositoryImpl");
        this.redisTemplate = redisTemplate;
    }

    @Override
    public void save(BrandStandardVO brandStandardVO) {
        ValueOperations<String, Serializable> opsForValue = redisTemplate.opsForValue();
        String key = BRAND_ITEM_PREFIX + brandStandardVO.getId();
        opsForValue.set(key, brandStandardVO);
        SetOperations<String, Serializable> opsForSet = redisTemplate.opsForSet();
        opsForSet.add(BRAND_ALL_KEYS_KEY, key);
    }

    @Override
    public void save(List<BrandListItemVO> brandListItemVOList) {
        ListOperations<String, Serializable> ops = redisTemplate.opsForList();
        for (BrandListItemVO brand : brandListItemVOList) {
            ops.rightPush(BRAND_LIST_KEY, brand);
        }
        SetOperations<String, Serializable> opsForSet = redisTemplate.opsForSet();
        opsForSet.add(BRAND_ALL_KEYS_KEY, BRAND_LIST_KEY);
    }

    @Override
    public void deleteAll() {
        SetOperations<String, Serializable> opsForSet = redisTemplate.opsForSet();
        Set<Serializable> serializableSet = opsForSet.members(BRAND_ALL_KEYS_KEY);
        Set<String> keys = new HashSet<>();
        assert serializableSet != null;
        for (Serializable serializable : serializableSet) {
            keys.add((String) serializable);
        }
        // 删除 key为"brand:item:*"和"brand:list"对应的value
        redisTemplate.delete(keys);
        // 删除 key为"brand:all-key"对应的value
        redisTemplate.delete(BRAND_ALL_KEYS_KEY);
    }

    @Override
    public BrandStandardVO get(Long id) {
        ValueOperations<String, Serializable> ops = redisTemplate.opsForValue();
        Serializable serializable = ops.get(BRAND_ITEM_PREFIX + id);
        if (serializable != null) {
            return (BrandStandardVO) serializable;
        }
        return null;
    }

    @Override
    public List<BrandListItemVO> list() {
        return list(0, -1);
    }

    @Override
    public List<BrandListItemVO> list(long start, long end) {
        ListOperations<String, Serializable> ops = redisTemplate.opsForList();
        List<Serializable> brands = ops.range(BRAND_LIST_KEY, start, end);
        ArrayList<BrandListItemVO> list = new ArrayList<>();
        assert brands != null;
        for (Serializable brand : brands) {
            list.add((BrandListItemVO) brand);
        }
        return list;
    }

}
